const path = require('path');
// 引入 ESLint 的语法检查插件
const ESLintPlugin = require('eslint-webpack-plugin');
// 打包编译html文件的插件
const HtmlWebpackPlugin = require('html-webpack-plugin');
// 抽离css文件
const MiniCssExtractPlugin = require("mini-css-extract-plugin")

// 处理css和js的压缩
const mode = process.env.NODE_ENV;
let CssMinimizerPlugin, TerserPlugin;
if (mode === 'production') {
    CssMinimizerPlugin = require('css-minimizer-webpack-plugin');
    TerserPlugin = require("terser-webpack-plugin");
}

const options = {
    // 核心1： 模式  'development',   // production
    mode,

    // 核心2： 入口
    entry: './src/main.js',

    // 核心3： 输出
    output: {
        path: path.resolve(__dirname, 'dist'),
        filename: 'js/bundle-[hash:8].js'
    },

    // 核心4： loader
    module: {
        rules: [
            // 处理css
            {
                test: /\.css$/,
                use: [
                    MiniCssExtractPlugin.loader,
                    'css-loader',
                    'postcss-loader'
                ]
            },
            // 处理less
            {
                test: /\.less$/,
                use: [
                    MiniCssExtractPlugin.loader,
                    'css-loader',
                    'postcss-loader',
                    'less-loader'
                ]
            },

            // 处理js的高级语法解析
            {
                test: /\.js$/,
                // 排除 node_modules
                exclude: /node_modules/,
                use: {
                    // loader的名称
                    loader: 'babel-loader',
                    // loader 的配置
                    options: {
                        presets: [
                            [
                                '@babel/preset-env',
                                {
                                    // 只打包使用的ES6新API的实现代码
                                    useBuiltIns: 'usage',
                                    // 指定core-js的版本号为2
                                    corejs: { version: 2 }
                                }
                            ]
                        ],
                        plugins: []
                    }
                }
            },

            // 处理背景图片和base64位格式的处理
            {
                test: /\.(jpg|png|gif|jpeg|bmp|webp)$/,
                type: "asset",
                // 解析器
                parser: {
                    // 指定进行图片base64编码最大文件大小
                    dataUrlCondition: {
                        maxSize: 5 * 1024, // 5kb    默认8k
                    }
                },
                // 打包生成的文件
                generator: {
                    filename: 'images/[hash:8][ext]',
                },
            },

            // 处理插入图片
            {
                test: /\.(html)$/,
                use: {
                    loader: 'html-loader'
                }
            },

            // 处理字体图标
            {
                test: /\.(eot|svg|woff|woff2|ttf)$/,
                type: 'asset',
                // 解析器
                parser: {
                    // 指定进行base64编码最大文件大小
                    dataUrlCondition: {
                        maxSize: 5 * 1024, // 5kb
                    }
                },
                generator: {
                    filename: 'fonts/[hash:8][ext]',
                },
            }
        ]
    },

    // 核心5： 插件
    plugins: [
        // 创建语法检查的实例
        new ESLintPlugin(),

        // 创建编译的指定模板配置实例
        new HtmlWebpackPlugin({
            template: "./public/index.html",
            // 在指定的模板文件中自动注入打包之后的js
            inject: "body",
            // 注入js之后，会自动加入哈希，避免读取缓存的内容
            hash: true,
            minify: {
                // 移除属性中的双引号
                removeAttributeQuotes: true,
                // 移除注释
                removeComments: true,
                // 去除空格与换行
                collapseWhitespace: true,
            }
        }),

        // 创建抽离css文件的实例
        new MiniCssExtractPlugin({
            filename: "css/[hash:8].css",
        })
    ]
}

// 通过模式进行判断是否添加对应的规则
if (mode === 'development') {
    // 开启虚拟服务
    options.devServer = {
        port: 8080,
        open: true
    }
    // 在开发阶段的时候生成的报错提示行号
    options.devtool = 'cheap-module-source-map'
} else {
    options.optimization = {
        minimizer: [
            new CssMinimizerPlugin(),
            new TerserPlugin()
        ]
    }
}

module.exports = options

